﻿// ------------------------------------------------------------------------------------
//      Copyright (c) 2012 uhavemyword@gmail.com. All rights reserved.
//      Created by Ben at 12/24/2012 7:13:16 PM
// ------------------------------------------------------------------------------------

namespace CP.NLayer.Data
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.IO;
    using System.Reflection;
    using CP.General;
    using CP.NLayer.Models;
    using CP.NLayer.Models.Entities;

    internal class MyDbInitializer : DropCreateDatabaseAlways<MyDbContext> //DropCreateDatabaseIfModelChanges
    {
        private MyDbContext _context;

        protected override void Seed(MyDbContext context)
        {
            _context = context;

            //_context.Database.ExecuteSqlCommand("ALTER TABLE User ADD CONSTRAINT uc_UserName UNIQUE(UserName)");
            this.ExecuteSqlScripts(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "SqlScripts"));
            this.InsertUsersAndRoles();
        }

        private void InsertUsersAndRoles()
        {
            var users = new List<User>
                {
                    new User() { LoginName = "User1", PasswordHash = AESEncryption.Encrypt("a", null), IsActive = true, Email = "user@126.com", FullName = "User 1", ContactInfo = null },
                    new User() { LoginName = "User2", PasswordHash = AESEncryption.Encrypt("a", null), IsActive = true, Email = "user@126.com", FullName = "User 2", ContactInfo = null },
                    new User() { LoginName = "User3", PasswordHash = AESEncryption.Encrypt("a", null), IsActive = true, Email = "user@126.com", FullName = "User 3", ContactInfo = null },
                    new User() { LoginName = "User4", PasswordHash = AESEncryption.Encrypt("a", null), IsActive = true, Email = "user@126.com", FullName = "User 4", ContactInfo = null },
                    new User() { LoginName = "User5", PasswordHash = AESEncryption.Encrypt("a", null), IsActive = true, Email = "user@126.com", FullName = "User 5", ContactInfo = null }
                };
            users.ForEach(i => _context.Users.Add(i));

            var roles = new List<Role>
                {
                    new Role() { Name = "Role1" },
                    new Role() { Name = "Role2" },
                    new Role() { Name = "Role3" },
                    new Role() { Name = "Role4" }
                };
            roles.ForEach(i => _context.Roles.Add(i));

            var permissions = new List<Permission>
            {
                new Permission() { Name = "UserManagement", Description = "UserManagement", CodeEnum = PermissionCodeEnum.UserManagement, Group = "System", DisplayOrder = 0 },
                new Permission() { Name = "RoleManagement", Description = "RoleManagement", CodeEnum = PermissionCodeEnum.RoleManagement, Group = "System", DisplayOrder = 1 },
            };
            permissions.ForEach(i => _context.Permissions.Add(i));

            roles[0].Users.Add(users[0]);
            users[1].Roles.Add(roles[1]);
            users[1].Roles.Add(roles[1]);
            users[1].Roles.Add(roles[2]);
            users[2].Roles.Remove(roles[1]);
            roles[0].Permissions.Add(permissions[0]);
            _context.SaveChanges();
        }

        /// <summary>
        /// Execute all SQL files under specified folder. 
        /// The statements in *.sql should be seperated by Environment.NewLine + "GO"
        /// </summary>
        /// <param name="folderPath"></param>
        private void ExecuteSqlScripts(string folderPath)
        {
            if (!Directory.Exists(folderPath))
            {
                return;
            }

            var filePaths = Directory.GetFiles(folderPath, "*.sql", SearchOption.AllDirectories);
            foreach (var filePath in filePaths)
            {
                var sqlText = File.ReadAllText(filePath);
                var sqls = sqlText.Split(new string[] { Environment.NewLine + "GO" }, StringSplitOptions.None);

                foreach (string sql in sqls)
                {
                    if (!string.IsNullOrEmpty(sql.Trim()))
                    {
                        _context.Database.ExecuteSqlCommand(sql);
                    }
                }
            }
        }
    }
}
